/**
 * 
 */
package l1j.opqlo.假人系統;


import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TimerTask;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.opqlo.Server.L1World.L1World;
import l1j.server.Config;
import l1j.server.Thread.GeneralThreadPool;
import l1j.server.server.IdFactory;
import l1j.server.server.datatables.NpcTable;
import l1j.server.server.model.L1Location;
import l1j.server.server.model.Instance.L1DummyInstance;
import l1j.server.server.model.map.L1Map;
import l1j.server.server.utils.Random;

/**
 * @author user
 *
 */
public class DummyThread extends TimerTask {

	private static final Logger _log = Logger.getLogger(DummyThread.class.getName());

	private static DummyThread _instance;

	private static boolean _isfull;

	public static DummyThread getInstance(){
		if(_instance == null){
			_instance = new DummyThread();
		}
		return _instance;
	}

	private static final HashMap<String , L1DummyInstance>_nameList = new HashMap<String , L1DummyInstance>();

	public boolean checkNameOnline(final String name){
		return _nameList.containsKey(name);
	}

	public L1DummyInstance getDummyTemp(final String name){
		return _nameList.get(name);
	}

	@Override
	public void run(){
		try {
			// 確認灌水系統
			updateDummyAmount();
			// 確認NPC個人商店-商店名稱切換
			//			updateShopName();
			// 確認NPC-聊天頻道 (1)
			//			checkNpcChatTime();
			// 確認NPC-聊天頻道 (2)
			//			checkNpcTalkTime();
			// 確認無限大賽時間
			//			checkUBTime();
			// 確認火把生成的時間
			//			checkLightTime();
			// 確認盟屋的稅金
			//			checkTaxDeadline();
			// 確認掃街系統
			//			checkStreetSweeping();
		} catch (final Exception e) {
			_log.log(Level.WARNING, "NPC死亡時間軸異常重啟", e);
			GeneralThreadPool.getInstance().cancel(this._timer, false);
			final DummyThread npcDeadTimer = new DummyThread();
			npcDeadTimer.start();
		}
	}
	private ScheduledFuture<?> _timer;
	public void start() {
		final int timeMillis = 40000;// 40秒
		this._timer = GeneralThreadPool.getInstance().scheduleAtFixedRate(this,timeMillis, timeMillis);
	}
	private boolean _isClear;

	private final void updateDummyAmount(){
		try{
			if(L1World.getInstance().getAllPlayerSize() <40){
				if(_map1count >0 || _map2count >0 || _map3count >0 || _map4count >0){
					if(_isClear == false){
						Set<String> set =_nameList.keySet();
						Iterator<String>list = set.iterator();
						while(list.hasNext()){
							_nameList.get(list.next()).deleteMe();
						}
						_nameList.clear();
						_map1count =0;
						_map2count =0;
						_map3count =0;
						_map4count =0;
						_isfull = false;
						L1World.getInstance().clearDummyAmount();
					}
				}
				return;
			}
			if(_isfull){
				return;
			}
			//		if(L1World.getInstance().getBogusAmount() >1000){
			//			_isfull = true;
			//			return;
			//		}
			if(_isClear){
				_isClear = false;
			}
			L1World.getInstance().addDummyAmount();
			if(_map1count < _map1MAX){
				spawn1();
			} else if(_map2count < _map2MAX){
				spawn2();
			} else if(_map3count < _map3MAX){
				spawn3();
			}else if(_map4count < _map4MAX){
				spawn4();
			}else{
				_isfull = true;
			}
		}catch(Exception e){
			_log.log(Level.SEVERE, e.getLocalizedMessage() , e);
		}
	}
	private final int[] _gfxid = {371,363,2447};
	private final int[] _gfxid2={8978,8812,9003,8913,8774,8900,8851,6276,6277,6282};
	private final int _map1MAX = 40 , _map2MAX = 5 , _map3MAX = 5 , _map4MAX = 5;
	private int _map1count = 0 , _map2count = 0, _map3count = 0 ,_map4count = 0;

	private short map1 = 1784 , map2 = 370, map3 = 350, map4 = 4;

	private void spawn1() {
		try {
			String name = RobotTable.getInstance().getRandomName();
			if(name == null){
				_isfull = true;
				return ;
			}
			final L1DummyInstance npc = (L1DummyInstance) NpcTable.getInstance().newNpcInstance(97091);
			_nameList.put(name , npc);
			npc.setId(IdFactory.getInstance().nextId());
			npc.setMap(map1);
			npc.setLevelMent(RobotTable.getInstance().getLevelMent(name));
			final int chance = Random.nextInt(100)+1;
			if( Config.SERVERCE == 3){
				if(chance >=90){
					npc.setGfxId(RobotTable.getInstance().getGfxId(name));
				}else{
					npc.setGfxId(_gfxid[Random.nextInt(_gfxid.length)]);
				}
			}else{
				if(chance >=90){
					npc.setGfxId(RobotTable.getInstance().getGfxId(name));
				}else if(chance >=85){
					npc.setGfxId(_gfxid2[Random.nextInt(_gfxid2.length)]);
				}else{
					npc.setGfxId(_gfxid[Random.nextInt(_gfxid.length)]);
				}
			}
			final int chance2 = Random.nextInt(32767)+1;

			npc.setLawful(chance2);

			L1Location location = new L1Location(); 

			int tryCount = 0;
			do {
				final int x = Random.nextInt(99)+32722;
				final int y = Random.nextInt(58)+32804;
				tryCount++;
				location.set(x, y, map1);
				npc.setX(x);
				npc.setY(y);
				L1Map map = npc.getMap();
				if (map.isInMap(location)	&& map.isPassable(location) 
						&& (x <32750 || x>32757) 
						&& (y <32829 || y>32836 )) {
					break;
				}
				Thread.sleep(1);
			} while (tryCount < 50);

			if (tryCount >= 50) {
				npc.setX(32739);
				npc.setY(32807);
			}
			npc.setName(name);
			String title = RobotTable.getInstance().getRandomTitle();
			if(title !=null){
				npc.setTitle(title);
			}
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(Random.nextInt(8));
			npc.getMap().setPassable(npc.getX(), npc.getY(), false);
			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);
			npc.turnOnOffLight();
			//			npc.onNpcAI();
			_map1count++;
		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}


	private void spawn2() {
		try {
			String name = RobotTable.getInstance().getRandomName();
			if(name == null){
				_isfull = true;
				return;
			}
			final L1DummyInstance npc = (L1DummyInstance) NpcTable.getInstance().newNpcInstance(97091);
			_nameList.put(name , npc);
			npc.setId(IdFactory.getInstance().nextId());
			npc.setMap(map2);
			npc.setLevelMent(RobotTable.getInstance().getLevelMent(name));
			final int chance = Random.nextInt(100)+1;
			if(chance >=50){
				npc.setGfxId(RobotTable.getInstance().getGfxId(name));
			}else if(chance >=35){
				npc.setGfxId(_gfxid2[Random.nextInt(_gfxid2.length)]);
			}else{
				npc.setGfxId(_gfxid[Random.nextInt(_gfxid.length)]);
			}
			final int chance2 = Random.nextInt(32767)+1;

			npc.setLawful(chance2);

			L1Location location = new L1Location(); 

			int tryCount = 0;
			do {
				final int x = Random.nextInt(25)+32725;
				final int y = Random.nextInt(29)+32785;
				tryCount++;
				location.set(x, y, map2);
				npc.setX(x);
				npc.setY(y);
				L1Map map = npc.getMap();
				if (map.isInMap(location)	&& map.isPassable(location) ) {
					break;
				}
				Thread.sleep(1);
			} while (tryCount < 50);

			if (tryCount >= 50) {
				npc.setX(32725);
				npc.setY(32785);
			}
			npc.setName(name);
			String title = RobotTable.getInstance().getRandomTitle();
			if(title !=null){
				npc.setTitle(title);
			}
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(Random.nextInt(8));
			npc.getMap().setPassable(npc.getX(), npc.getY(), false);
			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);
			npc.turnOnOffLight();
			//			npc.onNpcAI();
			_map2count++;
		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}

	private void spawn3() {
		try {
			String name = RobotTable.getInstance().getRandomName();
			if(name == null){
				_isfull = true;
				return;
			}
			final L1DummyInstance npc = (L1DummyInstance) NpcTable.getInstance().newNpcInstance(97091);
			_nameList.put(name , npc);
			npc.setId(IdFactory.getInstance().nextId());
			npc.setMap(map3);
			npc.setLevelMent(RobotTable.getInstance().getLevelMent(name));
			final int chance = Random.nextInt(100)+1;
			if(chance >=90){
				npc.setGfxId(RobotTable.getInstance().getGfxId(name));
			}else if(chance >=85){
				npc.setGfxId(_gfxid2[Random.nextInt(_gfxid2.length)]);
			}else{
				npc.setGfxId(_gfxid[Random.nextInt(_gfxid.length)]);
			}
			final int chance2 = Random.nextInt(32767)+1;

			npc.setLawful(chance2);

			L1Location location = new L1Location(); 

			int tryCount = 0;
			do {
				final int x = Random.nextInt(24)+32688;
				final int y = Random.nextInt(33)+32814;
				tryCount++;
				location.set(x, y, map3);
				npc.setX(x);
				npc.setY(y);
				L1Map map = npc.getMap();
				if (map.isInMap(location)	&& map.isPassable(location) ) {
					break;
				}
				Thread.sleep(1);
			} while (tryCount < 50);

			if (tryCount >= 50) {
				npc.setX(32688);
				npc.setY(32814);
			}
			npc.setName(name);
			String title = RobotTable.getInstance().getRandomTitle();
			if(title !=null){
				npc.setTitle(title);
			}
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(Random.nextInt(8));
			npc.getMap().setPassable(npc.getX(), npc.getY(), false);
			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);
			npc.turnOnOffLight();
			//			npc.onNpcAI();
			_map3count++;
		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}

	private void spawn4() {
		try {
			String name = RobotTable.getInstance().getRandomName();
			if(name == null){
				_isfull = true;
				return;
			}
			final L1DummyInstance npc = (L1DummyInstance) NpcTable.getInstance().newNpcInstance(97091);
			_nameList.put(name , npc);
			npc.setId(IdFactory.getInstance().nextId());
			npc.setMap(map4);
			npc.setLevelMent(RobotTable.getInstance().getLevelMent(name));
			final int chance = Random.nextInt(100)+1;
			if(chance >=90){
				npc.setGfxId(RobotTable.getInstance().getGfxId(name));
			}else if(chance >=85){
				npc.setGfxId(_gfxid2[Random.nextInt(_gfxid2.length)]);
			}else{
				npc.setGfxId(_gfxid[Random.nextInt(_gfxid.length)]);
			}
			final int chance2 = Random.nextInt(32767)+1;

			npc.setLawful(chance2);

			L1Location location = new L1Location(); 

			int tryCount = 0;
			do {
				final int x = Random.nextInt(29)+33061;
				final int y = Random.nextInt(22)+33390;
				tryCount++;
				location.set(x, y, map4);
				npc.setX(x);
				npc.setY(y);
				L1Map map = npc.getMap();
				if (map.isInMap(location)	&& map.isPassable(location) ) {
					break;
				}
				Thread.sleep(1);
			} while (tryCount < 50);

			if (tryCount >= 50) {
				npc.setX(33061);
				npc.setY(33390);
			}
			npc.setName(name);
			String title = RobotTable.getInstance().getRandomTitle();
			if(title !=null){
				npc.setTitle(title);
			}
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(Random.nextInt(8));
			npc.getMap().setPassable(npc.getX(), npc.getY(), false);
			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);
			npc.turnOnOffLight();
			//			npc.onNpcAI();
			_map4count++;
		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}

	/*
	private static boolean sweepStreetStart;

	public static final boolean isSweepStreetStart()
	{
		return sweepStreetStart;
	}

	private final void checkStreetSweeping()
	{
		 Calendar nowTime = Calendar.getInstance();

        if (nowTime.get(Calendar.HOUR_OF_DAY) >= Config.SweepStreet_Start && nowTime.get(Calendar.HOUR_OF_DAY) <= Config.SweepStreet_End && !sweepStreetStart)
        {
        	sweepStreetStart = true;

        	for (L1PcInstance pc : L1World.getInstance().getAllPlayers())
        	{
        		for (L1PcInstance known : pc.getKnownPlayers())
        		{
        			pc.sendPackets(new S_OtherCharPacks(known));
        			known.sendPackets(new S_PinkName(pc.getId(), 0xff));
        		}

        		pc.getParty().leaveMember(pc); // 自動解除隊伍
        	}
        }
        else if (!(nowTime.get(Calendar.HOUR_OF_DAY) >= Config.SweepStreet_Start && nowTime.get(Calendar.HOUR_OF_DAY) <= Config.SweepStreet_End) && sweepStreetStart)
        {
        	sweepStreetStart = false;

        	for (L1PcInstance pc : L1World.getInstance().getAllPlayers())
        	{
        		for (L1PcInstance known : pc.getKnownPlayers())
        		{
        			pc.sendPackets(new S_OtherCharPacks(known));
        			pc.broadcastPacket(new S_PinkName(pc.getId(), 0));
        		}
        	}
        }
	}
	 */
	//	private final void checkTaxDeadline()
	//	{
	//		for (L1House house : HouseTable.getInstance().getHouseTableList())
	//		{
	//			if (!house.isOnSale()) { // 不檢查再拍賣的血盟小屋
	//				if (house.getTaxDeadline().before(getRealTime()))
	//				{
	//					sellHouse(house);
	//				}
	//			}
	//		}
	//	}
	//
	//	private final void sellHouse(L1House house)
	//	{
	//		AuctionBoardTable boardTable = new AuctionBoardTable();
	//		L1AuctionBoard board = new L1AuctionBoard();
	//		
	//		if (board != null)
	//		{
	//			// 在拍賣板張貼新公告
	//			int houseId = house.getHouseId();
	//			board.setHouseId(houseId);
	//			board.setHouseName(house.getHouseName());
	//			board.setHouseArea(house.getHouseArea());
	//			TimeZone tz = TimeZone.getTimeZone(Config.TIME_ZONE);
	//			Calendar cal = Calendar.getInstance(tz);
	//			cal.add(Calendar.DATE, 5); // 5天以後
	//			cal.set(Calendar.MINUTE, 0); //
	//			cal.set(Calendar.SECOND, 0);
	//			board.setDeadline(cal);
	//			board.setPrice(100000);
	//			board.setLocation(house.getLocation());
	//			board.setOldOwner("");
	//			board.setOldOwnerId(0);
	//			board.setBidder("");
	//			board.setBidderId(0);
	//			boardTable.insertAuctionBoard(board);
	//			house.setOnSale(true); // 設定為拍賣中
	//			house.setPurchaseBasement(true); // TODO: 翻譯 地下アジト未購入に設定
	//			cal.add(Calendar.DATE, Config.HOUSE_TAX_INTERVAL);
	//			house.setTaxDeadline(cal);
	//			HouseTable.getInstance().updateHouse(house); // 儲存到資料庫中
	//			
	//			// 取消之前的擁有者
	//			for (L1Clan clan : WorldClan.get().getAllClans())
	//			{
	//				if (clan.getHouseId() == houseId)
	//				{
	//					clan.setHouseId(0);
	//					ClanTable.getInstance().updateClan(clan);
	//				}
	//			}
	//		}
	//	}
	//	
	//	private final void checkLightTime()
	//	{
	//		int serverTime = L1GameTimeClock.getInstance().currentTime().getSeconds();
	//		int nowTime = serverTime % 86400;
	//		
	//		if ((nowTime >= ((5 * 3600) + 3300)) && (nowTime < ((17 * 3600) + 3300)))
	//		{
	//			if (isSpawn)
	//			{
	//				isSpawn = false;
	//				
	//				for (L1Object object : L1World.getInstance().getObject())
	//				{
	//					if (object instanceof L1FieldObjectInstance) 
	//					{
	//						L1FieldObjectInstance npc = (L1FieldObjectInstance) object;
	//						
	//						if (((npc.getNpcTemplate().get_npcId() == 81177) || (npc.getNpcTemplate().get_npcId() == 81178) ||
	//							(npc.getNpcTemplate().get_npcId() == 81179) || (npc.getNpcTemplate().get_npcId() == 81180) ||
	//							(npc.getNpcTemplate().get_npcId() == 81181)) && ((npc.getMapId() == 0) || (npc.getMapId() == 4)))
	//						{
	//							npc.deleteMe();
	//						}
	//					}
	//				}
	//			}
	//		}
	//		else if (((nowTime >= ((17 * 3600) + 3300)) && (nowTime <= 24 * 3600)) || ((nowTime >= 0 * 3600) && (nowTime < ((5 * 3600) + 3300))))
	//		{
	//			if (!isSpawn)
	//			{
	//				isSpawn = true;
	//				LightSpawnTable.getInstance();
	//			}
	//		}
	//	}

	//	private final void checkUBTime()
	//	{
	//		if (isTimeOut(15000))
	//		{
	//			for (L1UltimateBattle ub : UBTable.getInstance().getAllUb())
	//			{
	//				if (ub.checkUbTime() && !ub.isActive())
	//				{
	//					ub.start();
	//				}
	//			}
	//		}
	//	}
	//	
	//	private final void checkNpcTalkTime()
	//	{
	//		for (L1Object obj : L1World.getInstance().getObject())
	//		{
	//			if (!(obj instanceof L1NpcInstance))
	//			{
	//				continue;
	//			}
	//			
	//			A_DummyChatName.startDummyChat((L1NpcInstance) obj);
	//		}
	//		
	//		A_DummyChatName.nextIndex();
	//	}


	//	private long shopTime;
	//	
	//	private final void updateShopName()
	//	{
	//		if (System.currentTimeMillis() > shopTime)
	//		{
	//			shopTime = System.currentTimeMillis() + 3000;
	//			
	//			for (final L1DummyInstance npc : L1World.getInstance().getDummyList())
	//			{
	//				npc.broadcastPacketAll(new S_DoActionShop(npc.getId(), npc.getShopName()));
	//			}
	//		}
	//	}
	//	
	//	private final void checkNpcChatTime()
	//	{
	//		for (final L1NpcChat npcChat : NpcChatTable.getInstance().getAllGameTime())
	//		{
	//			if (isTimeOut(npcChat.getGameTime()))
	//			{
	//				int npcId = npcChat.getNpcId();
	//				
	//				for (L1Object obj : L1World.getInstance().getObject())
	//				{
	//					if (!(obj instanceof L1NpcInstance))
	//					{
	//						continue;
	//					}
	//					
	//					L1NpcInstance npc = (L1NpcInstance) obj;
	//					
	//					if (npc.getNpcTemplate().get_npcId() == npcId)
	//					{
	//						npc.startChat(L1NpcInstance.CHAT_TIMING_GAME_TIME);
	//					}
	//				}
	//			}
	//		}
	//	}

	//	private final boolean isTimeOut(int chatTime)
	//	{
	//		SimpleDateFormat sdf = new SimpleDateFormat("HHmm");
	//		Calendar realTime = getRealTime();
	//		int nowTime = Integer.valueOf(sdf.format(realTime.getTime()));
	//		return (nowTime == chatTime);
	//	}
	//
	//	private final Calendar getRealTime()
	//	{
	//		TimeZone _tz = TimeZone.getTimeZone(Config.TIME_ZONE);
	//		Calendar cal = Calendar.getInstance(_tz);
	//		return cal;
	//	}
}
